package main

import (
	"errors"
	"io/ioutil"
	"os"
	"path"
	"path/filepath"
	"runtime"
	"strings"

	"gopkg.in/yaml.v3"
)

// GetCurrentPath 获取当前执行文件路径，如果是临时目录则获取当前文件的的执行路径
func GetCurrentPath() (dir string, err error) {
	dir, err = GetCurrentAbPathByExecutable()
	if err != nil {
		return "", err
	}

	tmpDir, err := filepath.EvalSymlinks(os.TempDir())
	if err != nil {
		return "", err
	}

	if strings.Contains(dir, tmpDir) {
		var ok bool
		if dir, ok = GetFileDirectoryToCaller(2); !ok {
			return "", errors.New("failed to get path")
		}
	}

	return dir, nil
}

// GetCurrentAbPathByExecutable 获取当前执行文件绝对路径
func GetCurrentAbPathByExecutable() (string, error) {
	exePath, err := os.Executable()
	if err != nil {
		return "", err
	}
	res, _ := filepath.EvalSymlinks(exePath)
	return filepath.Dir(res), nil
}

// GetFileDirectoryToCaller 根据运行堆栈信息获取文件目录，skip 默认1
func GetFileDirectoryToCaller(opts ...int) (directory string, ok bool) {
	var filename string
	directory = ""
	skip := 1
	if opts != nil {
		skip = opts[0]
	}
	if _, filename, _, ok = runtime.Caller(skip); ok {
		directory = path.Dir(filename)
	}
	return
}

func loadYaml() {
	var yamlConfig string
	runDirectory, _ := GetCurrentPath()
	yamlConfig = filepath.Join(runDirectory, "/config.yaml")

	cfg, err := ioutil.ReadFile(yamlConfig)
	if err != nil {
		panic("Failed to read configuration file:" + err.Error())
	}
	err = yaml.Unmarshal(cfg, &Config)
	if err != nil {
		panic("Failed to load configuration:" + err.Error())
	}
}

// Conf 配置项主结构体
type Conf struct {
	AppConfig `ini:"app" yaml:"app"`
	Server    ServerConfig `ini:"server" yaml:"server"`
}

var Config = &Conf{
	AppConfig: App,
	Server:    Server,
}

type ServerConfig struct {
	Host string `ini:"host" yaml:"host"`
	Port uint16 `ini:"port" yaml:"port"`
}

type AppConfig struct {
	Auth string `yaml:"auth"`
}

var App = AppConfig{
	Auth: "123456",
}

var Server = ServerConfig{
	Host: "0.0.0.0",
	Port: 8000,
}
